package com.jy.rhin.domain.document.validation;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jy.api.upload.UploadAPI;
import com.jy.api.upload.dto.Base64FileDto;
import com.jy.common.UIDWorker;
import com.jy.rhin.infra.repo.document.submission.mapper.DocumentValidateResultDetailMapper;
import com.jy.rhin.infra.repo.document.submission.mapper.DocumentValidateResultMapper;
import com.jy.rhin.infra.repo.document.submission.po.DocumentValidateResultDetailPO;
import com.jy.rhin.infra.repo.document.submission.po.DocumentValidateResultPO;
import com.jy.rhin.infra.repo.document.validation.mapper.DocumentValidationFileMapper;
import com.jy.rhin.sdk.dto.document.query.DocumentValidateResultDto;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 *
 */
@Service
public class DocumentValidateResultService
		extends ServiceImpl<DocumentValidateResultDetailMapper, DocumentValidateResultDetailPO>
		implements IDocumentValidataResultService {
	@Autowired
	private UIDWorker uidWorker;
	@Autowired
	private UploadAPI uploadAPI;
	@Autowired
	private DocumentValidateResultMapper documentValidateResultMapper;
	@Autowired
	private DocumentValidationFileMapper documentValidationFileMapper;
	@Override
	public void saveResult(DocumentValidateResultDto result) {
		DocumentValidateResultPO r = new DocumentValidateResultPO();
		BeanUtils.copyProperties(result, r);
		r.setDocumentId(result.getDocumentId());
		long id = uidWorker.nextId();
    	r.setId(id);
    	r.setRuleNum(documentValidationFileMapper.getRuleNum(result.getDocumentType()));
    	documentValidateResultMapper.insert(r);
        List<DocumentValidateResultDetailPO> details = new ArrayList<DocumentValidateResultDetailPO>();
    	result.getDetails().forEach(d->{
    		DocumentValidateResultDetailPO po = new DocumentValidateResultDetailPO();
    		BeanUtils.copyProperties(d, po);
    		po.setId(uidWorker.nextId());
    		po.setResultId(id);
    		details.add(po);
    	});
		saveBatch(details);
		
	}
	@Override
	public String getDownURL(List<Long> ids)  {

		String url = null;
		String filePath = "cda/"+uidWorker.nextId();
		try {
			Map<String,String> names = new HashMap<>();
			names.put("个人基本健康信息登记","EHR-SD-01-个人基本信息-");
			names.put("传染病报告","EHR-SD-10-传染病报告-");
			names.put("高血压患者随访服务","EHR-SD-12-高血患者随记服务-");
			names.put("2型糖尿病患者随访服务","EHR-SD-13-2型糖尿病患者随访服务-");
			names.put("成人健康体检","EHR-SD-16-成人健康体检-");
			names.put("门诊摘要","EHR-SD-17-门诊摘要-");
			names.put("住院摘要","EHR-SD-18-住院摘要-");
			//获取所有文件
			List<DocumentValidateResultPO> list = getByIds(ids);
			//写入文件
			list.forEach(l->{
				String fileName =names.get(l.getDocumentType())+l.getBingRenXM()+"-"+l.getDocumentId()+".xml";
				xieRuWJ(filePath+"/"+fileName,l.getXml());
			});
			//压缩文件
			File zipFile = fileToZip(filePath);
			//上传文件
			url = getWenJURL(zipFile);
			zipFile.delete();
			new File(filePath).delete();
		} catch (Exception e) {
			log.error("获取格式zip error:{}", e);
		}
		return url;
	}
	private List<DocumentValidateResultPO> getByIds(List<Long> ids){
		LambdaQueryWrapper<DocumentValidateResultPO> query = new LambdaQueryWrapper<DocumentValidateResultPO>();
		query.in(DocumentValidateResultPO::getId,ids);
		return documentValidateResultMapper.selectList(query);
	}


	private String getWenJURL(File file) throws Exception{
		FileInputStream fileInputStream = new FileInputStream(file);
		byte[] bytes = new byte[(int) file.length()];
		fileInputStream.read(bytes);
		String base64 = Base64.getEncoder().encodeToString(bytes);
		Base64FileDto base64File = new Base64FileDto();
		base64File.setBase64String(base64);
		base64File.setServiceName("data-integration");
		base64File.setFeildName(file.getName());
		base64File.setFileType("application/x-zip-compressed");
		fileInputStream.close();
		return uploadAPI.uploadByFeildName(base64File).getData();
	}
	private void xieRuWJ(String filePath, String str){
		File dataTransFile = new File(filePath);
		try {
			FileUtils.writeStringToFile(dataTransFile, str, "UTF-8");
		} catch (IOException e) {
			log.error("字符串写到文件error:{}", e);
		}
	}
	private File fileToZip(String sourceFile) throws Exception {
		File file = new File(sourceFile);
		//zip文件生成位置
		LocalDateTime currentDateTime = LocalDateTime.now();
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");

		String formattedDateTime = currentDateTime.format(formatter);
		File zipFile = new File(sourceFile+"/"+"共享文档下载-" + formattedDateTime+".zip");
		FileOutputStream fos = new FileOutputStream(zipFile);
		ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(fos));
		fileToZip(zos, file);
		zos.close();
		fos.close();
		for (File fileChr : file.listFiles()) {
			if(fileChr.getName().contains(".xml")){
				fileChr.delete();
			}
		}
		return zipFile;
	}
	private static void fileToZip(ZipOutputStream zos, File sourceFile) throws Exception {
		//如果是文件夹只创建zip实体即可，如果是文件，创建zip实体后还要读取文件内容并写入
		if (sourceFile.isDirectory()) {
			for (File file : sourceFile.listFiles()) {
				if(file.getName().contains(".xml")){
					fileToZip(zos, file);
				}
			}
		} else {
			//创建ZIP实体，并添加进压缩包
			ZipEntry zipEntry = new ZipEntry( sourceFile.getName());
			zos.putNextEntry(zipEntry);
			byte[] bufs = new byte[1024 * 10];
			//读取待压缩的文件并写进压缩包里
			FileInputStream fis = new FileInputStream(sourceFile);
			BufferedInputStream bis = new BufferedInputStream(fis, 1024 * 10);
			int read = 0;
			while ((read = bis.read(bufs, 0, 1024 * 10)) != -1) {
				zos.write(bufs, 0, read);
			}
			bis.close();
			fis.close();
		}
	}
}
